<!DOCTYPE HTML>
<html lang="en">


<head>
    <meta charset="utf-8">
    <meta name="keywords" content="webpack打包工具, blog">
    <meta name="description" content="不向前走怎么行呢">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="renderer" content="webkit|ie-stand|ie-comp">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <!-- Global site tag (gtag.js) - Google Analytics -->


    <title>webpack打包工具 | 王大锤学编程</title>
    <link rel="icon" type="image/png" href="/favicon.png">

    <link rel="stylesheet" type="text/css" href="/libs/awesome/css/all.css">
    <link rel="stylesheet" type="text/css" href="/libs/materialize/materialize.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/aos/aos.css">
    <link rel="stylesheet" type="text/css" href="/libs/animate/animate.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/lightGallery/css/lightgallery.min.css">
    <link rel="stylesheet" type="text/css" href="/css/matery.css">
    <link rel="stylesheet" type="text/css" href="/css/my.css">

    <script src="/libs/jquery/jquery.min.js"></script>

<meta name="generator" content="Hexo 5.3.0"></head>




<body>
    <header class="navbar-fixed">
    <nav id="headNav" class="bg-color nav-transparent">
        <div id="navContainer" class="nav-wrapper container">
            <div class="brand-logo">
                <a href="/" class="waves-effect waves-light">
                    
                    <img src="/medias/logo.png" class="logo-img" alt="LOGO">
                    
                    <span class="logo-span">王大锤学编程</span>
                </a>
            </div>
            

<a href="#" data-target="mobile-nav" class="sidenav-trigger button-collapse"><i class="fas fa-bars"></i></a>
<ul class="right nav-menu">
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/" class="waves-effect waves-light">
      
      <i class="fas fa-home" style="zoom: 0.6;"></i>
      
      <span>Index</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/tags" class="waves-effect waves-light">
      
      <i class="fas fa-tags" style="zoom: 0.6;"></i>
      
      <span>Tags</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/categories" class="waves-effect waves-light">
      
      <i class="fas fa-bookmark" style="zoom: 0.6;"></i>
      
      <span>Categories</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/archives" class="waves-effect waves-light">
      
      <i class="fas fa-archive" style="zoom: 0.6;"></i>
      
      <span>Archives</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/about" class="waves-effect waves-light">
      
      <i class="fas fa-user-circle" style="zoom: 0.6;"></i>
      
      <span>About</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/contact" class="waves-effect waves-light">
      
      <i class="fas fa-comments" style="zoom: 0.6;"></i>
      
      <span>Contact</span>
    </a>
    
  </li>
  
  <li>
    <a href="#searchModal" class="modal-trigger waves-effect waves-light">
      <i id="searchIcon" class="fas fa-search" title="Search" style="zoom: 0.85;"></i>
    </a>
  </li>
</ul>


<div id="mobile-nav" class="side-nav sidenav">

    <div class="mobile-head bg-color">
        
        <img src="/medias/logo.png" class="logo-img circle responsive-img">
        
        <div class="logo-name">王大锤学编程</div>
        <div class="logo-desc">
            
            不向前走怎么行呢
            
        </div>
    </div>

    

    <ul class="menu-list mobile-menu-list">
        
        <li class="m-nav-item">
	  
		<a href="/" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-home"></i>
			
			Index
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/tags" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-tags"></i>
			
			Tags
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/categories" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-bookmark"></i>
			
			Categories
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/archives" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-archive"></i>
			
			Archives
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/about" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-user-circle"></i>
			
			About
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/contact" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-comments"></i>
			
			Contact
		</a>
          
        </li>
        
        
    </ul>
</div>


        </div>

        
    </nav>

</header>

    



<div class="bg-cover pd-header post-cover" style="background-image: url('/medias/featureimages/7.jpg')">
    <div class="container" style="right: 0px;left: 0px;">
        <div class="row">
            <div class="col s12 m12 l12">
                <div class="brand">
                    <h1 class="description center-align post-title">webpack打包工具</h1>
                </div>
            </div>
        </div>
    </div>
</div>




<main class="post-container content">

    
    <link rel="stylesheet" href="/libs/tocbot/tocbot.css">
<style>
    #articleContent h1::before,
    #articleContent h2::before,
    #articleContent h3::before,
    #articleContent h4::before,
    #articleContent h5::before,
    #articleContent h6::before {
        display: block;
        content: " ";
        height: 100px;
        margin-top: -100px;
        visibility: hidden;
    }

    #articleContent :focus {
        outline: none;
    }

    .toc-fixed {
        position: fixed;
        top: 64px;
    }

    .toc-widget {
        width: 345px;
        padding-left: 20px;
    }

    .toc-widget .toc-title {
        padding: 35px 0 15px 17px;
        font-size: 1.5rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    .toc-widget ol {
        padding: 0;
        list-style: none;
    }

    #toc-content {
        padding-bottom: 30px;
        overflow: auto;
    }

    #toc-content ol {
        padding-left: 10px;
    }

    #toc-content ol li {
        padding-left: 10px;
    }

    #toc-content .toc-link:hover {
        color: #42b983;
        font-weight: 700;
        text-decoration: underline;
    }

    #toc-content .toc-link::before {
        background-color: transparent;
        max-height: 25px;

        position: absolute;
        right: 23.5vw;
        display: block;
    }

    #toc-content .is-active-link {
        color: #42b983;
    }

    #floating-toc-btn {
        position: fixed;
        right: 15px;
        bottom: 76px;
        padding-top: 15px;
        margin-bottom: 0;
        z-index: 998;
    }

    #floating-toc-btn .btn-floating {
        width: 48px;
        height: 48px;
    }

    #floating-toc-btn .btn-floating i {
        line-height: 48px;
        font-size: 1.4rem;
    }
</style>
<div class="row">
    <div id="main-content" class="col s12 m12 l9">
        <!-- 文章内容详情 -->
<div id="artDetail">
    <div class="card">
        <div class="card-content article-info">
            <div class="row tag-cate">
                <div class="col s7">
                    
                    <div class="article-tag">
                        
                            <a href="/tags/tools/">
                                <span class="chip bg-color">tools</span>
                            </a>
                        
                    </div>
                    
                </div>
                <div class="col s5 right-align">
                    
                    <div class="post-cate">
                        <i class="fas fa-bookmark fa-fw icon-category"></i>
                        
                            <a href="/categories/tools/" class="post-category">
                                tools
                            </a>
                        
                    </div>
                    
                </div>
            </div>

            <div class="post-info">
                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-minus fa-fw"></i>Publish Date:&nbsp;&nbsp;
                    2017-09-18
                </div>
                

                

                
                <div class="info-break-policy">
                    <i class="far fa-file-word fa-fw"></i>Word Count:&nbsp;&nbsp;
                    3.4k
                </div>
                

                
                <div class="info-break-policy">
                    <i class="far fa-clock fa-fw"></i>Read Times:&nbsp;&nbsp;
                    13 Min
                </div>
                

                
            </div>
        </div>
        <hr class="clearfix">

        
        <!-- 是否加载使用自带的 prismjs. -->
        <link rel="stylesheet" href="/libs/prism/prism.css">
        

        

        <div class="card-content article-card-content">
            <div id="articleContent">
                <h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>webpack是一个基于Node.js的应用程序模块打包器(module bundler)。它把项目中用到的的所有资源（图片、js文件、css文件等）都看成模块。当 webpack 处理应用程序时，它会从某个入口出发，递归地构建一个模块依赖关系图，其中包含项目用到的每个模块，然后将所有这些模块打包成一个或多个静态资源。</p>
<p><img src="http://wx3.sinaimg.cn/mw690/c2da5891gy1foxefdhs9cj20fe07gaag.jpg" alt=""></p>
<p>在功能上，webpack和gulp有类似的地方，比如文件合并，less/sass预编译，自动刷新浏览器，版本控制等。<br>但是两者定位是不同的：</p>
<ul>
<li>gulp强调流程控制；</li>
<li>webpack强调的是模块化开发。<br>如果你关注搭建项目的流程，就使用gulp，如果你关注的是项目的整体，就使用webpack。但不得不说，webpack是未来的趋势。</li>
</ul>
<h1 id="基本使用"><a href="#基本使用" class="headerlink" title="基本使用"></a>基本使用</h1><p>在命令行中通过npm命令即可全局安装：<br><code>npm install –g webpack</code><br>安装完成后输入以下命令检测是否安装成功：<br><code>webpack –v</code><br>新建一个项目目录，并初始化：<br><code>npm  init</code><br>在项目根目录下本地安装webpack：<br><code>npm install webpack –d</code><br><img src="http://wx4.sinaimg.cn/mw690/c2da5891gy1foxegysv6mj20be0b8myf.jpg" alt=""></p>
<p>使用webpack命令将src目录中的main.js 打包成一个指定的文件bundle.js<br><code>webpack   src/js/main.js   dist/js/bundle.js</code></p>
<p><img src="http://wx1.sinaimg.cn/mw690/c2da5891gy1foxei86rw1j20bg0ba0tx.jpg" alt=""></p>
<p><img src="http://wx2.sinaimg.cn/mw690/c2da5891gy1foxeiag8qij20an0bk0tx.jpg" alt=""></p>
<p>index.html中使用打包后的bundle.js文件。<br><img src="http://wx3.sinaimg.cn/mw690/c2da5891gy1foxejardfcj209x0bjwfh.jpg" alt=""><br>我们可以看到main.js中的js代码在index.html页面中成功执行。</p>
<h1 id="加载器"><a href="#加载器" class="headerlink" title="加载器"></a>加载器</h1><p>仅仅打包JavaScript文件还不能看出webpack的强大。接下来我们在src中准备一个CSS文件，其中包含了一些样式。用webpack将其打包。<br><img src="http://wx3.sinaimg.cn/mw690/c2da5891gy1foxeks2ztlj20aq09kwfj.jpg" alt=""></p>
<p>webpack不能直接打包CSS文件。因此，想要打包CSS文件，就需要让它和某个JS文件产生关联。webpack打包时会将关联的文件一并打包。js文件可以使用require，import，url等方式关联其它文件。</p>
<p>我们在main.js中加入如下代码，表示引用了main.css文件。</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"../css/main.css"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>如果这时就直接打包会发生以下错误：<br><img src="http://wx1.sinaimg.cn/mw690/c2da5891gy1foxeku9yq7j20ok0640sz.jpg" alt=""></p>
<p>webpack只能处理JavaScript代码。<br>在打包时，发现了一个它不能处理的CSS文件。<br>因此我们需要用到文件对应的加载器loader。<br>比如处理CSS文件就要用到两个加载器：</p>
<ul>
<li>css-loader</li>
<li>style-loader</li>
</ul>
<p>加载器的作用是：</p>
<blockquote>
<p>将模块的源码进行转换成webpack可以识别的代码，使得webpack有能力调用外部的脚本或工具，实现对不同格式的文件的处理，比如说分析转换less为css，转换ES6为ES5等。</p>
</blockquote>
<p>加载器也是通过npm命令安装：<br><code>npm install css-loader style-loader -d</code></p>
<h2 id="使用方式一"><a href="#使用方式一" class="headerlink" title="使用方式一"></a>使用方式一</h2><p>加载器的使用方式一：在关联时，在路径前加上加载器名字和感叹号。</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"style-loader!css-loader!../css/main.css"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>修改代码之后再次打包：<br><code>webpack  src/js/main.js  dist/js/bundle.js</code><br>main.js文件的代码和index.css代码都会被打包到bundle.js中。<br>这样，我们只引入了一个脚本文件，却同时具备了脚本和样式。</p>
<p>对于不同文件的处理，需要用到不同的加载器。<br>比如：<br>处理.js文件需要用到js-loader，<br>处理.less文件需要用到less-loader，<br>……</p>
<p>同时使用多个加载器时，用感叹号连接。webpack会按照从后向前的顺序使用。<br>    如：</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"style-loader!css-loader!./index.css"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>上述代码流程如下：<br>先使用css-loader加载器加载css文件，得到css样式规则，<br>再使用style-loader加载器加载上一步的样式规则，创建style标签并插入html页面。</p>
<h1 id="配置文件"><a href="#配置文件" class="headerlink" title="配置文件"></a>配置文件</h1><p>前面的案例就是webpack基本应用。<br>但是需要在命令行中输入的内容还是比较多，在开发中一般采用配置文件的形式，将一些具体的信息写入文件中，更加方便而且可以避免出错。<br>配置文件应该命名为webpack.config.js，并放在项目的根目录下。<br><img src="http://wx4.sinaimg.cn/mw690/c2da5891gy1foxeolvsknj20b207xmy6.jpg" alt=""><br>配置文件的内容可以包含很多信息，以下配置包含了入口文件和输入路径：</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
    <span class="token comment">//入口文件的路径</span>
    entry<span class="token operator">:</span> <span class="token string">'/src/main.js'</span><span class="token punctuation">,</span>
    output<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
        <span class="token comment">//打包后的文件存放的绝对路径</span>
        path<span class="token operator">:</span> __dirname <span class="token operator">+</span> <span class="token string">'/dist/js'</span><span class="token punctuation">,</span>
        <span class="token comment">//打包后输出文件的文件名</span>
        filename<span class="token operator">:</span> <span class="token string">'bundle.js'</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="入口"><a href="#入口" class="headerlink" title="入口"></a>入口</h2><p>entry属性用来设置入口文件，非常重要，webpack就是通过它来寻找其关联的模块的。<br>入口属性有三种写法：</p>
<ol>
<li>String， 表示打包单个入口文件到一个文件。<br> 如 entry: “./src/main.js”,</li>
<li>String Array，表示打包多个入口文件到同一个文件。（不推荐使用）<br> 如 entry: [“./src/main1.js”, “./src/main2.js”]</li>
<li>Object，表示打包多个入口文件到不同文件。（扩展性高）<br> 如 <pre class="line-numbers language-js" data-language="js"><code class="language-js">entry<span class="token operator">:</span><span class="token punctuation">&#123;</span>
        pageOne<span class="token operator">:</span> <span class="token string">'./src/pageOne/index.js'</span><span class="token punctuation">,</span>
        pageTwo<span class="token operator">:</span> <span class="token string">'./src/pageTwo/index.js'</span><span class="token punctuation">,</span>
        pageThree<span class="token operator">:</span> <span class="token string">'./src/pageThree/index.js'</span>
    <span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="输出"><a href="#输出" class="headerlink" title="输出"></a>输出</h2>output属性用来设置打包结果的输出路径。<br>当只打包成一个文件时，就直接文件路径即可：<br><code>filename: &quot;bundle.js &quot;</code><br>如果需要打包成多个文件，文件名就要使用占位符：<br><code>filename: &quot;[name].js&quot;</code></li>
</ol>
<p>占位符：<br><code>[name]</code>，        会被entry对象中对应的key值替换，<br><code>[hash]</code>，        会被打包后的模块的hash值替换<br><code>[chunkhash]</code>，    会被打包之前的模块hash值替换。</p>
<h2 id="在配置文件中使用加载器"><a href="#在配置文件中使用加载器" class="headerlink" title="在配置文件中使用加载器"></a>在配置文件中使用加载器</h2><p>加载器的使用方式二（推荐）：<br>在使用加载器loader的时候，我们也可以直接在webpack.config.js文件中进行配置：</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
    entry<span class="token operator">:</span> __dirname <span class="token operator">+</span> <span class="token string">'/src/main.js'</span><span class="token punctuation">,</span>
    output<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
	path<span class="token operator">:</span> __dirname <span class="token operator">+</span> <span class="token string">'/dist/js'</span><span class="token punctuation">,</span>
	filename<span class="token operator">:</span> <span class="token string">'bundle.js'</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
    module<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
        rules<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">&#123;</span>  <span class="token comment">//处理每一种文件都可以在rules数组中添加一个对象</span>
            test<span class="token operator">:</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\.css$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span>   <span class="token comment">//用正则表达式匹配css文件</span>
            use<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">'style-loader'</span><span class="token punctuation">,</span> <span class="token string">'css-loader'</span><span class="token punctuation">,</span> <span class="token string">'postcss-loader'</span><span class="token punctuation">]</span>  <span class="token comment">//指定使用的加载器</span>
	   exclude<span class="token operator">:</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">node_modules</span><span class="token regex-delimiter">/</span></span>    <span class="token comment">//排除node_modules目录</span>
        <span class="token punctuation">&#125;</span><span class="token punctuation">]</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>配置文件中的加载器的use属性取值有三种:</p>
<ul>
<li>表示加载器名字的字符串</li>
<li>对象，可以添加额外的属性</li>
<li>装有多个加载器名字的字符串数组或装有多个加载器对象的对象数组。</li>
</ul>
<h1 id="处理资源文件"><a href="#处理资源文件" class="headerlink" title="处理资源文件"></a>处理资源文件</h1><p>处理资源文件时，需要用到一些插件。<br>插件是webpack的核心功能，目的在于解决加载器无法解决的问题。<br>有时候，加载器也会配合插件和其他工具一起使用。</p>
<p>通过插件，webpack可以实现一些与gulp相同的功能：<br>压缩HTML，CSS，HTML…等等。</p>
<p>使用插件时，必须先安装，再到webpack.config.js文件中进行相关配置。</p>
<h2 id="自动生成html插件"><a href="#自动生成html插件" class="headerlink" title="自动生成html插件"></a>自动生成html插件</h2><p>之前的操作，我们是自己在dist目录下建立的index.html文件，然后手动引用生成的js等资源文件的。当需要应用的链接过多时会比较麻烦。<br>我们可以使用html-webpack-plugin插件来生成HTML文件并自动引用js文件。</p>
<p>npm命令安装：<br><code>npm install html-webpack-plugin --save</code></p>
<p>html-webpack-plugin插件使用：</p>
<ol>
<li>在配置文件中引入插件<pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> htmlWebpackPlugin <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span>'html<span class="token operator">-</span>webpack<span class="token operator">-</span>plugin’<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre></li>
<li>在配置文件导出的对象中添加plugins属性<pre class="line-numbers language-js" data-language="js"><code class="language-js">plugins<span class="token operator">:</span> <span class="token punctuation">[</span>
    <span class="token keyword">new</span> <span class="token class-name">htmlWebpackPlugin</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">]</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li>
<li>重新打包，即可看到生成了一个空白的html文件，并自动引用了打包生成的bundle.js。</li>
</ol>
<p>html-webpack-plugin插件输出的路径和output的path一致，<br>我们可以修改output属性，使html文件直接输出到dist/目录中。</p>
<p>修改前：</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js">output<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
	path<span class="token operator">:</span> __dirname <span class="token operator">+</span> <span class="token string">"/dist/js"</span><span class="token punctuation">,</span>
	filename<span class="token operator">:</span> <span class="token string">"js/[name].js"</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<p>修改后：</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js">output<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
	path<span class="token operator">:</span> __dirname <span class="token operator">+</span> <span class="token string">"/dist"</span><span class="token punctuation">,</span>
	filename<span class="token operator">:</span> <span class="token string">"js/[name].js"</span>
<span class="token punctuation">&#125;</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<p>插件的构造函数是可以接收一个配置参数对象，便于进行一些复杂的设置。<br>如：</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> options <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
	filename<span class="token operator">:</span> <span class="token string">'home.html'</span> <span class="token punctuation">,</span>   <span class="token comment">//生成的html文件的名字，默认是index.html</span>
	inject<span class="token operator">:</span> <span class="token string">'head'</span><span class="token punctuation">,</span>      <span class="token comment">//注入文档的哪个位置，有true，false，body，head四个取值。</span>
  favicon<span class="token operator">:</span> <span class="token string">'images/favicon.ico'</span><span class="token punctuation">,</span> <span class="token comment">//为html文件引入一个图标</span>
  hash<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>    <span class="token comment">// 是否为js文件添加上一个hash值，方便浏览器缓存</span>
  cache<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">,</span> <span class="token comment">//是否在内容发生变化时才生成新的文件。</span>
  removeComments<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>	<span class="token comment">//是否清除HTML注释  </span>
  collapseWhitespace<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>	<span class="token comment">//是否压缩HTML  </span>
  removeScriptTypeAttributes<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>	<span class="token comment">//是否删除&lt;script>的type="text/javascript"  </span>
  removeStyleLinkTypeAttributes<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>	<span class="token comment">//是否删除&lt;style>和&lt;link>的type="text/css"  </span>
  minifyJS<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>	<span class="token comment">//是否压缩页面JS  </span>
  minifyCSS<span class="token operator">:</span> <span class="token boolean">true</span>	<span class="token comment">//是否压缩页面CSS  </span>
<span class="token punctuation">&#125;</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>其它参数：</p>
<ul>
<li>chunks：<br>有多个入口文件被打包时，就会编译成多个js文件，chunks可以决定在html文件中都应用哪些js文件。默认会引用全部。excludeChunks的功能刚好相反，表示排除。<pre class="line-numbers language-js" data-language="js"><code class="language-js">entry<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
        pageOne<span class="token operator">:</span> <span class="token string">'./src/pageOne/index.js'</span><span class="token punctuation">,</span>
        pageTwo<span class="token operator">:</span> <span class="token string">'./src/pageTwo/index.js'</span><span class="token punctuation">,</span>
        pageThree<span class="token operator">:</span> <span class="token string">'./src/pageThree/index.js'</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
plugins<span class="token operator">:</span> <span class="token punctuation">[</span>
        <span class="token keyword">new</span> <span class="token class-name">htmlWebpackPlugin</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
            chunks<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">"pageOne"</span><span class="token punctuation">,</span> <span class="token string">"pageTwo"</span><span class="token punctuation">]</span>
        <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token punctuation">]</span>
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li>
<li>publicPath<br>如果项目上线时，打包的js文件要单独放在另外的服务器中，我们可以使用该属性设置路径的域名。如：<br>publicPath: “<a target="_blank" rel="noopener" href="http://cdn.com/“">http://cdn.com/“</a><br>生成的html文件中的引用路径就是：<br><a target="_blank" rel="noopener" href="http://cdn.com/dist/js/bundle.js">http://cdn.com/dist/js/bundle.js</a></li>
<li>title<br>生成的html文件的标题，但是配置该属性我们不能直接看到效果。<br>除非我们在模板文件中使用一些特殊的语法，如：<pre class="line-numbers language-html" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">></span></span> &lt; % = htmlWebpackPlugin.options.title % > <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
如果你还记得ejs模板引擎的话，不难看出这里的语法和ejs的语法是一样的。</li>
</ul>
<p>注意：如果使用的是其它类型的模板，应该安装相应的加载器。<br>html-webpack-plugin插件中使用模板时，如果没有单独指定模板的类型，那么就默认使用的是ejs模板，并使用ejs-loader来处理所有类型的模板文件。即使文件的后缀名为.html。因此我们可以直接在模板文件中使用ejs的语法。</p>
<p>刚才使用的htmlWebpackPlugin对象其实就是我们在webpack.confic.js文件中new出来的那个对象。<br>htmlWebpackPlugin.options是我们传递给构造函数的那个配置对象。<br>htmlWebpackPlugin.options.title拿到的是我们设置的那个标题!</p>
<p>因此，我们可以在生成的页面上使用ejs语法来设置很多的数据。<br>配置对象的参数基本就这么多，灵活添加适当的参数就可以让我们的开发更加简化。</p>
<p>之前我们只是自动生成一个html文件，<br>如果需要同时自动生成多个html文件，可以这样做：</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js">plugins<span class="token operator">:</span> <span class="token punctuation">[</span>
  <span class="token keyword">new</span> <span class="token class-name">htmlWebpackPlugin</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token keyword">new</span> <span class="token class-name">htmlWebpackPlugin</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token keyword">new</span> <span class="token class-name">htmlWebpackPlugin</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">)</span>
<span class="token punctuation">]</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>只需要分别给每一个页面对应的配置即可。</p>
<h2 id="处理CSS文件"><a href="#处理CSS文件" class="headerlink" title="处理CSS文件"></a>处理CSS文件</h2><p>之前我们已经使用过 css-loader和style-loader处理CSS文件了。<br>但是实际开发中的情况更加复杂，还需要进一步处理。<br>postcss是专注于处理CSS的一个平台。这个平台上有很多的插件帮助我们更加便捷地编写CSS代码。比如自动添加浏览器前缀等等…</p>
<p>在webpack中是以加载器的形式存在。<br>安装：<br><code>npm install postcss-loader --save</code><br>Postcss平台在webpack的使用有些特别，<br>从webpack 3.x开始就不用在webpack.config.js中配置了。<br>而是单独建立一个名为：postcss.config.js的文件，并添加如下内容：</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
    plugins<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
        <span class="token string">'autoprefixer'</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span> browsers<span class="token operator">:</span> <span class="token string">'last 5 version'</span> <span class="token punctuation">&#125;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>上述代码的意思就是在postcss平台中使用autoprefixer插件来为css添加浏览器前缀。<br>我们需要使用postcss平台中的什么插件，就在这里配置即可。</p>
<p>开发中常常会把Less文件编译成CSS代码。<br>Webpack需要下载专门处理less文件的加载器—-less-loader。<br>安装：<br><code>npm install less-loader -d</code></p>
<p>如果没有安装过less模块，还需要安装less。<br><code>npm install less -d</code></p>
<p>使用less-loader只需要在webpack.config.js中配置一下加载器即可：</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js"> module<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
  rules<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">&#123;</span>
      test<span class="token operator">:</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\.less$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span>
      use<span class="token operator">:</span> <span class="token punctuation">[</span>
          <span class="token string">'style-loader'</span><span class="token punctuation">,</span> <span class="token string">'css-loader'</span><span class="token punctuation">,</span> <span class="token string">'postcss-loader'</span><span class="token punctuation">,</span> <span class="token string">'less-loader'</span>
      <span class="token punctuation">]</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">]</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>这里的顺序要注意，less-loader应该最先被使用。</p>
<h2 id="转码js"><a href="#转码js" class="headerlink" title="转码js"></a>转码js</h2><p>Babel是一个将ES6或者其他类型的js语言转换成浏览器能支持的ES5的工具。<br>这样我们就可以在编程时使用新特性，打包时再进行转换。<br>安装：<br><code>npm install -d babel-loader bable-core</code></p>
<p>Babel是一个JavaScript编译器，可以将ES6或者其他类型的js语言转换成浏览器能支持的ES5。它可以在webpack等工具中使用。<br>这样我们就可以在编程时使用新特性，打包时再进行转换。</p>
<p>安装：<br><code>npm install babel-loader @babel/core @babel/preset-env</code></p>
<p>配置：</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js"> module<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
  rules<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">&#123;</span>
      test<span class="token operator">:</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\.js$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span>
      exclude<span class="token operator">:</span> ‘<span class="token operator">/</span>node_modules<span class="token operator">/</span>’<span class="token punctuation">,</span>      <span class="token comment">//排除某个文件夹</span>
      include<span class="token operator">:</span><span class="token string">'/src'</span> <span class="token punctuation">,</span>    <span class="token comment">//转码的文件夹</span>
      use<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
          loader<span class="token operator">:</span> <span class="token string">'babel-loader'</span><span class="token punctuation">,</span>
          options<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
              presets<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">'@babel/preset-env'</span><span class="token punctuation">]</span>
          <span class="token punctuation">&#125;</span>
      <span class="token punctuation">&#125;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">]</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>重新打包之后，<br>我们可以看到新生成的js文件中的ES6等新语法都变成了所有浏览器都支持的ES5。</p>
<h2 id="处理图片文件以及其它文件"><a href="#处理图片文件以及其它文件" class="headerlink" title="处理图片文件以及其它文件"></a>处理图片文件以及其它文件</h2><p>处理文件需要用到file-loader加载器，<br>安装：<br><code>npm install fle-loader -d</code><br>在webpack.config.js中配置：</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js">module<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
  rules<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">,</span> <span class="token punctuation">&#123;</span>
      test<span class="token operator">:</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\.(jpg|gif|png|svg|jpeg)$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span>
      use<span class="token operator">:</span> <span class="token string">'file-loader'</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">]</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>这样在css等文件中引用的文件就会被打包到html文件的同级目录中。<br>注意，只有用url，require，import关键字引用的文件才会被file-loader处理，如果直接在html文件中写的资源文件是不会被打包的，如：</p>
<pre class="line-numbers language-html" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>../images/0.jpg<span class="token punctuation">"</span></span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>要使得文件被打包，需要这样写：</p>
<pre class="line-numbers language-html" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>$&#123; require(<span class="token punctuation">'</span>../images/0.jpg<span class="token punctuation">'</span>)&#125;<span class="token punctuation">"</span></span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>打包的文件的目标路径默认是和html文件同级。而且文件名也变了。<br>我们可以这样来指定打包的文件的路径和文件名：</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js">module<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
       rules<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">&#123;</span>
           test<span class="token operator">:</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\.(jpg|gif|png|svg|jpeg)$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span>
           use<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
               loader<span class="token operator">:</span> <span class="token string">'file-loader'</span><span class="token punctuation">,</span>
               query<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
                   name<span class="token operator">:</span> <span class="token string">'images/[name].[ext]'</span>
               <span class="token punctuation">&#125;</span>
           <span class="token punctuation">&#125;</span>
       <span class="token punctuation">&#125;</span><span class="token punctuation">]</span>
   <span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

                
            </div>
            <hr/>

            

    <div class="reprint" id="reprint-statement">
        
            <div class="reprint__author">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-user">
                        Author:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="/about" rel="external nofollow noreferrer">wanglian</a>
                </span>
            </div>
            <div class="reprint__type">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-link">
                        Link:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="https://github.com/fernandozhaxi/fernandozhaxi.github.io/2017/09/18/webpack/">https://github.com/fernandozhaxi/fernandozhaxi.github.io/2017/09/18/webpack/</a>
                </span>
            </div>
            <div class="reprint__notice">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-copyright">
                        Reprint policy:
                    </i>
                </span>
                <span class="reprint-info">
                    All articles in this blog are used except for special statements
                    <a href="https://creativecommons.org/licenses/by/4.0/deed.zh" rel="external nofollow noreferrer" target="_blank">CC BY 4.0</a>
                    reprint polocy. If reproduced, please indicate source
                    <a href="/about" target="_blank">wanglian</a>
                    !
                </span>
            </div>
        
    </div>

    <script async defer>
      document.addEventListener("copy", function (e) {
        let toastHTML = '<span>Copied successfully, please follow the reprint policy of this article</span><button class="btn-flat toast-action" onclick="navToReprintStatement()" style="font-size: smaller">more</a>';
        M.toast({html: toastHTML})
      });

      function navToReprintStatement() {
        $("html, body").animate({scrollTop: $("#reprint-statement").offset().top - 80}, 800);
      }
    </script>



            <div class="tag_share" style="display: block;">
                <div class="post-meta__tag-list" style="display: inline-block;">
                    
                        <div class="article-tag">
                            
                                <a href="/tags/tools/">
                                    <span class="chip bg-color">tools</span>
                                </a>
                            
                        </div>
                    
                </div>
                <div class="post_share" style="zoom: 80%; width: fit-content; display: inline-block; float: right; margin: -0.15rem 0;">
                    <link rel="stylesheet" type="text/css" href="/libs/share/css/share.min.css">
<div id="article-share">

    
    <div class="social-share" data-sites="twitter,facebook,google,qq,qzone,wechat,weibo,douban,linkedin" data-wechat-qrcode-helper="<p>微信扫一扫即可分享！</p>"></div>
    <script src="/libs/share/js/social-share.min.js"></script>
    

    

</div>

                </div>
            </div>
            
        </div>
    </div>

    

    

    

    

    
        <style>
    .valine-card {
        margin: 1.5rem auto;
    }

    .valine-card .card-content {
        padding: 20px 20px 5px 20px;
    }

    #vcomments textarea {
        box-sizing: border-box;
        background: url("/medias/comment_bg.png") 100% 100% no-repeat;
    }

    #vcomments p {
        margin: 2px 2px 10px;
        font-size: 1.05rem;
        line-height: 1.78rem;
    }

    #vcomments blockquote p {
        text-indent: 0.2rem;
    }

    #vcomments a {
        padding: 0 2px;
        color: #4cbf30;
        font-weight: 500;
        text-decoration: none;
    }

    #vcomments img {
        max-width: 100%;
        height: auto;
        cursor: pointer;
    }

    #vcomments ol li {
        list-style-type: decimal;
    }

    #vcomments ol,
    ul {
        display: block;
        padding-left: 2em;
        word-spacing: 0.05rem;
    }

    #vcomments ul li,
    ol li {
        display: list-item;
        line-height: 1.8rem;
        font-size: 1rem;
    }

    #vcomments ul li {
        list-style-type: disc;
    }

    #vcomments ul ul li {
        list-style-type: circle;
    }

    #vcomments table, th, td {
        padding: 12px 13px;
        border: 1px solid #dfe2e5;
    }

    #vcomments table, th, td {
        border: 0;
    }

    table tr:nth-child(2n), thead {
        background-color: #fafafa;
    }

    #vcomments table th {
        background-color: #f2f2f2;
        min-width: 80px;
    }

    #vcomments table td {
        min-width: 80px;
    }

    #vcomments h1 {
        font-size: 1.85rem;
        font-weight: bold;
        line-height: 2.2rem;
    }

    #vcomments h2 {
        font-size: 1.65rem;
        font-weight: bold;
        line-height: 1.9rem;
    }

    #vcomments h3 {
        font-size: 1.45rem;
        font-weight: bold;
        line-height: 1.7rem;
    }

    #vcomments h4 {
        font-size: 1.25rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    #vcomments h5 {
        font-size: 1.1rem;
        font-weight: bold;
        line-height: 1.4rem;
    }

    #vcomments h6 {
        font-size: 1rem;
        line-height: 1.3rem;
    }

    #vcomments p {
        font-size: 1rem;
        line-height: 1.5rem;
    }

    #vcomments hr {
        margin: 12px 0;
        border: 0;
        border-top: 1px solid #ccc;
    }

    #vcomments blockquote {
        margin: 15px 0;
        border-left: 5px solid #42b983;
        padding: 1rem 0.8rem 0.3rem 0.8rem;
        color: #666;
        background-color: rgba(66, 185, 131, .1);
    }

    #vcomments pre {
        font-family: monospace, monospace;
        padding: 1.2em;
        margin: .5em 0;
        background: #272822;
        overflow: auto;
        border-radius: 0.3em;
        tab-size: 4;
    }

    #vcomments code {
        font-family: monospace, monospace;
        padding: 1px 3px;
        font-size: 0.92rem;
        color: #e96900;
        background-color: #f8f8f8;
        border-radius: 2px;
    }

    #vcomments pre code {
        font-family: monospace, monospace;
        padding: 0;
        color: #e8eaf6;
        background-color: #272822;
    }

    #vcomments pre[class*="language-"] {
        padding: 1.2em;
        margin: .5em 0;
    }

    #vcomments code[class*="language-"],
    pre[class*="language-"] {
        color: #e8eaf6;
    }

    #vcomments [type="checkbox"]:not(:checked), [type="checkbox"]:checked {
        position: inherit;
        margin-left: -1.3rem;
        margin-right: 0.4rem;
        margin-top: -1px;
        vertical-align: middle;
        left: unset;
        visibility: visible;
    }

    #vcomments b,
    strong {
        font-weight: bold;
    }

    #vcomments dfn {
        font-style: italic;
    }

    #vcomments small {
        font-size: 85%;
    }

    #vcomments cite {
        font-style: normal;
    }

    #vcomments mark {
        background-color: #fcf8e3;
        padding: .2em;
    }

    #vcomments table, th, td {
        padding: 12px 13px;
        border: 1px solid #dfe2e5;
    }

    table tr:nth-child(2n), thead {
        background-color: #fafafa;
    }

    #vcomments table th {
        background-color: #f2f2f2;
        min-width: 80px;
    }

    #vcomments table td {
        min-width: 80px;
    }

    #vcomments [type="checkbox"]:not(:checked), [type="checkbox"]:checked {
        position: inherit;
        margin-left: -1.3rem;
        margin-right: 0.4rem;
        margin-top: -1px;
        vertical-align: middle;
        left: unset;
        visibility: visible;
    }
</style>

<div class="card valine-card" data-aos="fade-up">
    <div class="comment_headling" style="font-size: 20px; font-weight: 700; position: relative; padding-left: 20px; top: 15px; padding-bottom: 5px;">
        <i class="fas fa-comments fa-fw" aria-hidden="true"></i>
        <span>评论</span>
    </div>
    <div id="vcomments" class="card-content" style="display: grid">
    </div>
</div>

<script src="/libs/valine/av-min.js"></script>
<script src="/libs/valine/Valine.min.js"></script>
<script>
    new Valine({
        el: '#vcomments',
        appId: 'eA9KHUmCz3d6uLMHwpgFrU6D-gzGzoHsz',
        appKey: '6t2AadKbapH6Sni2PmSONMbI',
        notify: 'true' === 'true',
        verify: 'false' === 'true',
        visitor: 'true' === 'true',
        avatar: 'mm',
        pageSize: '10',
        lang: 'en',
        placeholder: 'judge me please!'
    });
</script>

    

    

    

    

    

<article id="prenext-posts" class="prev-next articles">
    <div class="row article-row">
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge left-badge text-color">
                <i class="fas fa-chevron-left"></i>&nbsp;Previous</div>
            <div class="card">
                <a href="/2017/10/11/vuerouter-lazyload/">
                    <div class="card-image">
                        
                        
                        <img src="/medias/featureimages/4.jpg" class="responsive-img" alt="vue-router按需加载">
                        
                        <span class="card-title">vue-router按需加载</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            
                        
                    </div>
                    <div class="publish-info">
                        <span class="publish-date">
                            <i class="far fa-clock fa-fw icon-date"></i>2017-10-11
                        </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/vue/" class="post-category">
                                    vue
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/vue-router/">
                        <span class="chip bg-color">vue-router</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge right-badge text-color">
                Next&nbsp;<i class="fas fa-chevron-right"></i>
            </div>
            <div class="card">
                <a href="/2017/09/16/bounce/">
                    <div class="card-image">
                        
                        
                        <img src="/medias/featureimages/13.jpg" class="responsive-img" alt="函数去抖和节流">
                        
                        <span class="card-title">函数去抖和节流</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            
                        
                    </div>
                    <div class="publish-info">
                            <span class="publish-date">
                                <i class="far fa-clock fa-fw icon-date"></i>2017-09-16
                            </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/javascript/" class="post-category">
                                    javascript
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/javascript/">
                        <span class="chip bg-color">javascript</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
    </div>
</article>

</div>


<script>
    $('#articleContent').on('copy', function (e) {
        // IE8 or earlier browser is 'undefined'
        if (typeof window.getSelection === 'undefined') return;

        var selection = window.getSelection();
        // if the selection is short let's not annoy our users.
        if (('' + selection).length < Number.parseInt('120')) {
            return;
        }

        // create a div outside of the visible area and fill it with the selected text.
        var bodyElement = document.getElementsByTagName('body')[0];
        var newdiv = document.createElement('div');
        newdiv.style.position = 'absolute';
        newdiv.style.left = '-99999px';
        bodyElement.appendChild(newdiv);
        newdiv.appendChild(selection.getRangeAt(0).cloneContents());

        // we need a <pre> tag workaround.
        // otherwise the text inside "pre" loses all the line breaks!
        if (selection.getRangeAt(0).commonAncestorContainer.nodeName === 'PRE') {
            newdiv.innerHTML = "<pre>" + newdiv.innerHTML + "</pre>";
        }

        var url = document.location.href;
        newdiv.innerHTML += '<br />'
            + 'From: 王大锤学编程<br />'
            + 'Author: wanglian<br />'
            + 'Link: <a href="' + url + '">' + url + '</a><br />'
            + '本文章著作权归作者所有，任何形式的转载都请注明出处。';

        selection.selectAllChildren(newdiv);
        window.setTimeout(function () {bodyElement.removeChild(newdiv);}, 200);
    });
</script>


<!-- 代码块功能依赖 -->
<script type="text/javascript" src="/libs/codeBlock/codeBlockFuction.js"></script>

<!-- 代码语言 -->

<script type="text/javascript" src="/libs/codeBlock/codeLang.js"></script>


<!-- 代码块复制 -->

<script type="text/javascript" src="/libs/codeBlock/codeCopy.js"></script>


<!-- 代码块收缩 -->

<script type="text/javascript" src="/libs/codeBlock/codeShrink.js"></script>


    </div>
    <div id="toc-aside" class="expanded col l3 hide-on-med-and-down">
        <div class="toc-widget card" style="background-color: white;">
            <div class="toc-title"><i class="far fa-list-alt"></i>&nbsp;&nbsp;TOC</div>
            <div id="toc-content"></div>
        </div>
    </div>
</div>

<!-- TOC 悬浮按钮. -->

<div id="floating-toc-btn" class="hide-on-med-and-down">
    <a class="btn-floating btn-large bg-color">
        <i class="fas fa-list-ul"></i>
    </a>
</div>


<script src="/libs/tocbot/tocbot.min.js"></script>
<script>
    $(function () {
        tocbot.init({
            tocSelector: '#toc-content',
            contentSelector: '#articleContent',
            headingsOffset: -($(window).height() * 0.4 - 45),
            collapseDepth: Number('0'),
            headingSelector: 'h2, h3, h4'
        });

        // modify the toc link href to support Chinese.
        let i = 0;
        let tocHeading = 'toc-heading-';
        $('#toc-content a').each(function () {
            $(this).attr('href', '#' + tocHeading + (++i));
        });

        // modify the heading title id to support Chinese.
        i = 0;
        $('#articleContent').children('h2, h3, h4').each(function () {
            $(this).attr('id', tocHeading + (++i));
        });

        // Set scroll toc fixed.
        let tocHeight = parseInt($(window).height() * 0.4 - 64);
        let $tocWidget = $('.toc-widget');
        $(window).scroll(function () {
            let scroll = $(window).scrollTop();
            /* add post toc fixed. */
            if (scroll > tocHeight) {
                $tocWidget.addClass('toc-fixed');
            } else {
                $tocWidget.removeClass('toc-fixed');
            }
        });

        
        /* 修复文章卡片 div 的宽度. */
        let fixPostCardWidth = function (srcId, targetId) {
            let srcDiv = $('#' + srcId);
            if (srcDiv.length === 0) {
                return;
            }

            let w = srcDiv.width();
            if (w >= 450) {
                w = w + 21;
            } else if (w >= 350 && w < 450) {
                w = w + 18;
            } else if (w >= 300 && w < 350) {
                w = w + 16;
            } else {
                w = w + 14;
            }
            $('#' + targetId).width(w);
        };

        // 切换TOC目录展开收缩的相关操作.
        const expandedClass = 'expanded';
        let $tocAside = $('#toc-aside');
        let $mainContent = $('#main-content');
        $('#floating-toc-btn .btn-floating').click(function () {
            if ($tocAside.hasClass(expandedClass)) {
                $tocAside.removeClass(expandedClass).hide();
                $mainContent.removeClass('l9');
            } else {
                $tocAside.addClass(expandedClass).show();
                $mainContent.addClass('l9');
            }
            fixPostCardWidth('artDetail', 'prenext-posts');
        });
        
    });
</script>

    

</main>




    <footer class="page-footer bg-color">
    
        <link rel="stylesheet" href="/libs/aplayer/APlayer.min.css">
<style>
    .aplayer .aplayer-lrc p {
        
        display: none;
        
        font-size: 12px;
        font-weight: 700;
        line-height: 16px !important;
    }

    .aplayer .aplayer-lrc p.aplayer-lrc-current {
        
        display: none;
        
        font-size: 15px;
        color: #42b983;
    }

    
    .aplayer.aplayer-fixed.aplayer-narrow .aplayer-body {
        left: -66px !important;
    }

    .aplayer.aplayer-fixed.aplayer-narrow .aplayer-body:hover {
        left: 0px !important;
    }

    
</style>
<div class="">
    
    <div class="row">
        <meting-js class="col l8 offset-l2 m10 offset-m1 s12"
                   server="netease"
                   type="playlist"
                   id="503838841"
                   fixed='true'
                   autoplay='false'
                   theme='#42b983'
                   loop='all'
                   order='random'
                   preload='auto'
                   volume='0.7'
                   list-folded='true'
        >
        </meting-js>
    </div>
</div>

<script src="/libs/aplayer/APlayer.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js"></script>

    
    <div class="container row center-align" style="margin-bottom: 0px !important;">
        <div class="col s12 m8 l8 copy-right">
            Copyright&nbsp;&copy;
            
                <span id="year">2019-2021</span>
            
            <span id="year">2019</span>
            <a href="/about" target="_blank">wanglian</a>
            |&nbsp;Powered by&nbsp;<a href="https://hexo.io/" target="_blank">Hexo</a>
            |&nbsp;Theme&nbsp;<a href="https://github.com/blinkfox/hexo-theme-matery" target="_blank">Matery</a>
            <br>
            
            &nbsp;<i class="fas fa-chart-area"></i>&nbsp;站点总字数:&nbsp;<span
                class="white-color">115.3k</span>&nbsp;字
            
            
            
            
            <span id="busuanzi_container_site_pv">
                |&nbsp;<i class="far fa-eye"></i>&nbsp;总访问量:&nbsp;<span id="busuanzi_value_site_pv"
                    class="white-color"></span>&nbsp;次
            </span>
            
            
            <span id="busuanzi_container_site_uv">
                |&nbsp;<i class="fas fa-users"></i>&nbsp;总访问人数:&nbsp;<span id="busuanzi_value_site_uv"
                    class="white-color"></span>&nbsp;人
            </span>
            
            <br>
            
            <br>
            
        </div>
        <div class="col s12 m4 l4 social-link ">




    <a href="https://www.facebook.com/xxx" class="tooltipped" target="_blank" data-tooltip="关注我的Facebook: https://www.facebook.com/xxx" data-position="top" data-delay="50">
        <i class="fab fa-facebook-f"></i>
    </a>



    <a href="https://twitter.com/xxx" class="tooltipped" target="_blank" data-tooltip="关注我的Twitter: https://twitter.com/xxx" data-position="top" data-delay="50">
        <i class="fab fa-twitter"></i>
    </a>





    <a href="https://weibo.com" class="tooltipped" target="_blank" data-tooltip="关注我的微博: https://weibo.com" data-position="top" data-delay="50">
        <i class="fab fa-weibo"></i>
    </a>



    <a href="https://www.zhihu.com" class="tooltipped" target="_blank" data-tooltip="关注我的知乎: https://www.zhihu.com" data-position="top" data-delay="50">
        <i class="fab fa-zhihu1">知</i>
    </a>



    <a href="/atom.xml" class="tooltipped" target="_blank" data-tooltip="RSS 订阅" data-position="top" data-delay="50">
        <i class="fas fa-rss"></i>
    </a>

</div>
    </div>
</footer>

<div class="progress-bar"></div>


    <!-- 搜索遮罩框 -->
<div id="searchModal" class="modal">
    <div class="modal-content">
        <div class="search-header">
            <span class="title"><i class="fas fa-search"></i>&nbsp;&nbsp;Search</span>
            <input type="search" id="searchInput" name="s" placeholder="Please enter a search keyword"
                   class="search-input">
        </div>
        <div id="searchResult"></div>
    </div>
</div>

<script type="text/javascript">
$(function () {
    var searchFunc = function (path, search_id, content_id) {
        'use strict';
        $.ajax({
            url: path,
            dataType: "xml",
            success: function (xmlResponse) {
                // get the contents from search data
                var datas = $("entry", xmlResponse).map(function () {
                    return {
                        title: $("title", this).text(),
                        content: $("content", this).text(),
                        url: $("url", this).text()
                    };
                }).get();
                var $input = document.getElementById(search_id);
                var $resultContent = document.getElementById(content_id);
                $input.addEventListener('input', function () {
                    var str = '<ul class=\"search-result-list\">';
                    var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/);
                    $resultContent.innerHTML = "";
                    if (this.value.trim().length <= 0) {
                        return;
                    }
                    // perform local searching
                    datas.forEach(function (data) {
                        var isMatch = true;
                        var data_title = data.title.trim().toLowerCase();
                        var data_content = data.content.trim().replace(/<[^>]+>/g, "").toLowerCase();
                        var data_url = data.url;
                        data_url = data_url.indexOf('/') === 0 ? data.url : '/' + data_url;
                        var index_title = -1;
                        var index_content = -1;
                        var first_occur = -1;
                        // only match artiles with not empty titles and contents
                        if (data_title !== '' && data_content !== '') {
                            keywords.forEach(function (keyword, i) {
                                index_title = data_title.indexOf(keyword);
                                index_content = data_content.indexOf(keyword);
                                if (index_title < 0 && index_content < 0) {
                                    isMatch = false;
                                } else {
                                    if (index_content < 0) {
                                        index_content = 0;
                                    }
                                    if (i === 0) {
                                        first_occur = index_content;
                                    }
                                }
                            });
                        }
                        // show search results
                        if (isMatch) {
                            str += "<li><a href='" + data_url + "' class='search-result-title'>" + data_title + "</a>";
                            var content = data.content.trim().replace(/<[^>]+>/g, "");
                            if (first_occur >= 0) {
                                // cut out 100 characters
                                var start = first_occur - 20;
                                var end = first_occur + 80;
                                if (start < 0) {
                                    start = 0;
                                }
                                if (start === 0) {
                                    end = 100;
                                }
                                if (end > content.length) {
                                    end = content.length;
                                }
                                var match_content = content.substr(start, end);
                                // highlight all keywords
                                keywords.forEach(function (keyword) {
                                    var regS = new RegExp(keyword, "gi");
                                    match_content = match_content.replace(regS, "<em class=\"search-keyword\">" + keyword + "</em>");
                                });

                                str += "<p class=\"search-result\">" + match_content + "...</p>"
                            }
                            str += "</li>";
                        }
                    });
                    str += "</ul>";
                    $resultContent.innerHTML = str;
                });
            }
        });
    };

    searchFunc('/search.xml', 'searchInput', 'searchResult');
});
</script>

    <!-- 回到顶部按钮 -->
<div id="backTop" class="top-scroll">
    <a class="btn-floating btn-large waves-effect waves-light" href="#!">
        <i class="fas fa-arrow-up"></i>
    </a>
</div>


    <script src="/libs/materialize/materialize.min.js"></script>
    <script src="/libs/masonry/masonry.pkgd.min.js"></script>
    <script src="/libs/aos/aos.js"></script>
    <script src="/libs/scrollprogress/scrollProgress.min.js"></script>
    <script src="/libs/lightGallery/js/lightgallery-all.min.js"></script>
    <script src="/js/matery.js"></script>

    <!-- Baidu Analytics -->

    <!-- Baidu Push -->

    
    <script src="/libs/others/clicklove.js" async="async"></script>
    
    

    

    

    <!--腾讯兔小巢-->
    
    

    

    

    
    <script src="/libs/instantpage/instantpage.js" type="module"></script>
    

</body>

</html>
